package org.jader.bolao.xml;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import org.jader.bolao.Championship;
import org.jader.bolao.CustomModality;
import org.jader.bolao.Game;
import org.jader.bolao.GamePlayer;
import org.jader.bolao.Group;
import org.jader.bolao.Phase;
import org.jader.bolao.Player;
import org.jader.bolao.Team;
import org.jader.bolao.beans.PropertyChanger;
import org.jader.html.HTMLReplacer;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.converters.ConversionException;
import com.thoughtworks.xstream.io.xml.DomDriver;

public class XMLFactory {

	public static Championship loadChampionship(File xmlFile) {
		String xml = "";
		HTMLReplacer replacer = new HTMLReplacer();
		try {
			StringBuffer fileData = new StringBuffer(1000);
	        BufferedReader reader = new BufferedReader(new FileReader(xmlFile));
	        char[] buf = new char[1024];
	        int numRead=0;
	        while((numRead=reader.read(buf)) != -1){
	            String readData = String.valueOf(buf, 0, numRead);
	            fileData.append(readData);
	            buf = new char[1024];
	        }
	        reader.close();
	        // Replace HTML cods
	        xml = replacer.replaceAllHTMLCodesBySpecialChar(fileData.toString());
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		// Remove Statistics
        int statsIndex = xml.indexOf("<ps>");
        if (statsIndex > 0) {
        	int endIndex = xml.indexOf("</cs>");
        	if (endIndex < statsIndex) endIndex = xml.indexOf("</ts>");
        	xml = xml.substring(0, statsIndex-1)+xml.substring(endIndex+5);
        }
		// Import XML data
		XStream xstream = initializeXStream();
		Championship c = null;
		try {
			c = (Championship) xstream.fromXML(xml);
		} catch (ConversionException e) {
			xstream.setMode(XStream.XPATH_RELATIVE_REFERENCES);
			c = (Championship) xstream.fromXML(xml);
		}
		c.refreshPropertyListeners();
		return c;
	}

	public static void saveChampionship(Championship c, File xmlFile) {
		// Write XML to file
		try {
			BufferedWriter out = new BufferedWriter(new FileWriter(xmlFile));
			out.write("<?xml version='1.0'  encoding='UTF-8' standalone='yes'?>\n\n");
			out.write(generateXML(c));
			out.close();
			c.saved();
		}
		catch (IOException e)
		{
			e.printStackTrace();		
		}
	}
	
	public static String generateXML(Championship c) {
		// Refresh necessary fields
		c.refreshFields();
		// Create XML data
		XStream xstream = initializeXStream();
		String xml = xstream.toXML(c);
		// Substitute special characters
		xml = new HTMLReplacer().replaceAllSpecialCharsByHTMLCode(xml);
		// Return XML
		return xml;
	}

	private static XStream initializeXStream() {
		XStream xstream = new XStream(new DomDriver()); // does not require XPP3 library
		xstream.alias("championship", Championship.class);
		xstream.alias("game", Game.class);
		xstream.alias("gameplayer", GamePlayer.class);
		xstream.alias("gametype", Game.Type.class);
		xstream.alias("player", Player.class);
		xstream.alias("team", Team.class);
		xstream.alias("phase", Phase.class);
		xstream.alias("group", Group.class);
		xstream.alias("teampointer", Group.TeamPointer.class);
		xstream.alias("modality", CustomModality.class);
		xstream.alias("modalityTeam", CustomModality.ModalityTeam.class);
		xstream.omitField(PropertyChanger.class, "propertyListeners");
		xstream.omitField(Championship.class, "changed");
		//xstream.omitField(GamePlayer.class, "TOTAL_BALLS");
		xstream.registerConverter(Championship.getConverter());
		xstream.setMode(XStream.ID_REFERENCES);
		return xstream;
	}
}
